module Api
    require "faraday"
    require 'sqlite3'
    require 'openssl'
    require 'json'
    require 'uri'
    class Bter
        @@exchanges = {
            :pair => "http://data.bter.com/api2/1/pairs",
            :marketinfo => 'http://data.bter.com/api2/1/marketinfo',
            :marketlist => 'http://data.bter.com/api2/1/marketlist',
            :tikers => 'http://data.bter.com/api2/1/tickers',
            :tiker => 'http://data.bter.com/api2/1/ticker/[CURR_A]_[CURR_B]',
            :order_books=>'http://data.bter.com/api2/1/orderBooks',
            :trade_history => 'http://data.bter.com/api2/1/tradeHistory/[CURR_A]_[CURR_B]',
            :deposite_address => ' https://api.bter.com/api2/1/private/depositeAddress',
            :deposite_withdrawals => 'https://api.bter.com/api2/1/private/depositsWithdrawals',
            :buy => 'https://api.bter.com/api2/1/private/buy',
            :sell => 'https://api.bter.com/api2/1/private/sell',
            :cancel_order => 'https://api.bter.com/api2/1/private/cancelOrder',
            :cancel_orders => 'https://api.bter.com/api2/1/private/cancelOrders',
            :cancel_all_orders => 'https://api.bter.com/api2/1/private/cancelAllOrders',
            :get_order => 'https://api.bter.com/api2/1/private/getOrder',
            :open_orders => 'https://api.bter.com/api2/1/private/openOrders',
            :trade_history_user => 'https://api.bter.com/api2/1/private/tradeHistory',
            :withdraw => 'https://api.bter.com/api2/1/private/withdraw'
        }
        def initialize(key,secret)
            @key = key
            @secret = secret
            @@exchanges.each_key do |k|
                if @@exchanges[k].index('[CURR_A]')!=nil then
                    self.class.send(:define_method,k) {|k1,k2|self.make_api(k,@@exchanges[k],k1,k2)}
                else
                    self.class.send(:define_method,k) {self.make_api(k,@@exchanges[k])}
                end
            end
        end
  
      def sign(params={})
        hmac = OpenSSL::HMAC.new(@secret,OpenSSL::Digest::SHA512.new)
        params = params.collect {|k,v| "#{k}=#{v}"}.join('&')
        hmac.update(params).to_s    
      end

        def make_api(k,v,k1=nil,k2=nil)
            if v.index("private") == nil then
                self.public_request(v,k1,k2)
            else
                self.private_request(v,k1,k2)
            end
        end

        def get(v)
            p = URI.parse(v)
            conn = Faraday.new(:url => p.scheme + "://"+p.host) do |c|
                c.use Faraday::Request::UrlEncoded  # encode request params as "www-form-urlencoded"
                c.use Faraday::Adapter::NetHttp     # perform requests with Net::HTTP
            end
            conn.headers[:user_agent] = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
            response = conn.get p.path
            if response.status==200 then
                JSON.parse(response.body)
            else
                nil
            end
        end
        def post(v,data=nil)
            p = URI.parse(v)
            conn = Faraday.new(:url => p.scheme + "://"+p.host,:ssl=>{:verify_mode=>OpenSSL::SSL::VERIFY_NONE}) do |c|
                #c.adapter :httpclient do |client| # yields HTTPClient
                #    client.keep_alive_timeout = 20
                #    client.ssl_config.timeout = 25
                #    client.ssl_config.verify_mode = OpenSSL::SSL::SSL_VERIFY_NONE
                #  end
                c.use Faraday::Request::UrlEncoded  # encode request params as "www-form-urlencoded"
                c.use Faraday::Adapter::NetHttp     # perform requests with Net::HTTP
            end
            conn.headers[:user_agent] = 'MyLib v1.2'
            conn.headers[:key] = @key
            conn.headers[:sign] = self.sign
            if data==nil then
                response = conn.post p.path
            else
                response = conn.post p.path data
            end
            if response.status==200 then
                JSON.parse(response.body)
            else
                nil
            end
        end

        def public_request(v,k1=nil,k2=nil)
            if k1!=nil then
                v = v.sub('[CURR_A]',k1).sub('[CURR_B]',k2)
            end
            self.get(v)
        end
        def private_request(v,k1=nil,k2=nil)
            self.post(v)
        end

    end
    
end


#q=Api::Bter.new('209BA9B0-5DBA-4787-92DF-E24EA8C9231A','cc1d4f861bb29ae1dd89244ad446e4636ead5817b54c4b68a5eb65395dcf6486')

#puts q.open_orders
